﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using Microsoft.Office.Tools.Ribbon;

namespace WildRiley.PPTFormatCodeAddin
{
    public partial class Ribbon1 : OfficeRibbon
    {
        // Default language to use for "Other" button
        private CodeFormatter.Language otherLanguage = CodeFormatter.Language.HTML;
        private bool acceptedEULA;
        private RegistryKey acceptedEULARegistryKey;
        private const string acceptedEULARegistryKeyValue = "AcceptedEULA";
        private const string addinType = "Powerpoint";

        public Ribbon1()
        {
            try
            {
                string acceptedEULARegistyKeyPath = String.Format(@"Software\WildRiley\{0}",
                    Assembly.GetExecutingAssembly().GetName().Name);
                acceptedEULARegistryKey = Registry.CurrentUser.OpenSubKey(acceptedEULARegistyKeyPath, true);
                if (acceptedEULARegistryKey == null)
                {
                    acceptedEULARegistryKey = Registry.CurrentUser.CreateSubKey(acceptedEULARegistyKeyPath, RegistryKeyPermissionCheck.ReadWriteSubTree);
                }

                acceptedEULA = GetSavedEULASetting();

                InitializeComponent();
                PopulateLanguages();

                // ValidateEULA();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Error Initializing Addin");
            }
        }

        /// <summary>
        /// Ensure user has accepted EULA terms before Addin runs
        /// </summary>
        /// <returns>true is EULA is accepted, else false</returns>
        bool ValidateEULA()
        {
            if (!this.acceptedEULA)
            {
                Eula eula = new Eula();
                if (eula.ShowDialog() == DialogResult.OK)
                {
                    this.acceptedEULA = true;
                    SaveEULASetting(this.acceptedEULA);
                }
            }

            return this.acceptedEULA;
        }

        /// <summary>
        /// Retrieves the saved value of the EULA setting.   
        /// </summary>
        /// <returns>If no value is present, returns false</returns>
        bool GetSavedEULASetting()
        {
            return Convert.ToBoolean(acceptedEULARegistryKey.GetValue(acceptedEULARegistryKeyValue, 
                false, RegistryValueOptions.DoNotExpandEnvironmentNames));
        }
        
        /// <summary>
        /// Persists the value as the EULA setting
        /// </summary>
        /// <param name="acceptedEULA">new EULA setting</param>
        /// <returns><paramref name="acceptedEULA"/></returns>
        bool SaveEULASetting(bool acceptedEULA)
        {
            acceptedEULARegistryKey.SetValue(acceptedEULARegistryKeyValue, acceptedEULA, RegistryValueKind.String);
            return acceptedEULA;
        }

        /// <summary>
        /// Update "other" button label when selected language changes
        /// </summary>
        private void UpdateSelectedLanguage()
        {
            // Update button with selected language
            this.buttonFormatOther.Label = String.Format("Other [{0}]", this.otherLanguage);
        }

        /// <summary>
        /// Populate set of available languages for use with the "other" button
        /// </summary>
        private void PopulateLanguages()
        {
            // Iterate over all possible langauges
            for (CodeFormatter.Language lang = 0; lang < CodeFormatter.Language.LanguageMax; lang++)
            {
                // Add button with language name and add click event handler
                //
                string langName = lang.ToString();
                Microsoft.Office.Tools.Ribbon.RibbonToggleButton button = new Microsoft.Office.Tools.Ribbon.RibbonToggleButton();
                button.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeRegular;
                button.Checked = lang == this.otherLanguage ? true : false;
                button.Label = langName;
                button.Name = "OtherButtonLanguage" + langName;
                button.OfficeImageId = "CitationInsert";
                button.ShowImage = true;
                button.ScreenTip = "Set language to " + langName;
                button.SuperTip = "Sets the current custom language format to " + langName;
                button.Click += new System.EventHandler<Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs>(this.buttonFormatSetOtherLanguage_Click);

                this.buttonFormatOther.Items.Add(button);
            }

            // Handle language selection
            UpdateSelectedLanguage();
        }
        
        private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
        {
        }

        private void FormatCodeSelection(CodeFormatter.Language lang)
        {
            if (ValidateEULA())
            {
                CodeFormatter.FormatCodeSelection(lang);
            }
        }

        /// <summary>
        /// CSharp button click handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnFormatCSharp_Click(object sender, RibbonControlEventArgs e)
        {
            FormatCodeSelection(CodeFormatter.Language.CSharp);
        }

        /// <summary>
        /// Xml button click handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonFormatXml_Click(object sender, RibbonControlEventArgs e)
        {
            FormatCodeSelection(CodeFormatter.Language.XML);
        }

        /// <summary>
        /// SQL button click handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonFormatSql_Click(object sender, RibbonControlEventArgs e)
        {
            FormatCodeSelection(CodeFormatter.Language.SQL);
        }

        /// <summary>
        /// Other button click handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonFormatOther_Click(object sender, RibbonControlEventArgs e)
        {
            FormatCodeSelection(this.otherLanguage);
        }

        /// <summary>
        /// Selected "other" language event handler (updates selected language)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonFormatSetOtherLanguage_Click(object sender, RibbonControlEventArgs e)
        {
            if (!ValidateEULA())
            {
                return;
            }

            // Custom language has changed - clear current entries
            foreach (RibbonControl control in this.buttonFormatOther.Items)
            {
                // Reset checked state
                Microsoft.Office.Tools.Ribbon.RibbonToggleButton button = control as Microsoft.Office.Tools.Ribbon.RibbonToggleButton;
                if (button != null)
                {
                    // Found this button (sender)
                    if (sender == button)
                    {
                        // Update checked state and reset selected language
                        button.Checked = true;
                        this.otherLanguage = (CodeFormatter.Language) Enum.Parse(typeof(CodeFormatter.Language), button.Label);
                    }
                    else
                    {
                        button.Checked = false;
                    }
                }
            }

            // Handle changes
            UpdateSelectedLanguage();
        }
    }
}
